<?php

/**
 * 仓库管理
 */

namespace app\admin\service;

use app\admin\model\RegionCity;
use app\admin\model\RegionCountry;
use think\Service;
use app\admin\model\Warehouse as WarehouseModel;
use \app\admin\model\TransactionCurrency as TransactionCurrencyModel;
use app\admin\model\ProductSoldStat as ProductSoldStatModel;

class Warehouse extends BaseService
{
    /**
     * 获取仓库列表
     * @param $param
     * @param $page
     * @param $limit
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getList($param = [], $page = 1, $limit = 10)
    {
        $where = [['is_del','=',0]];
        $arrData = ['code' => 0, 'message' => 'success'];
        if ($param['name']) {
            $where[] = ['name', 'like', '%' . $param['name'] . '%'];
        }

        $warehouse = WarehouseModel::where('fl_warehouse_id','EXP','IS NULL')->field('id,name')->select();
        $parentName = [];
        foreach ($warehouse as $key => $value) {
            $parentName[$value['id']] = $value['name'];
        }

        $oWarehouseModel = WarehouseModel::where($where);
        $total = $oWarehouseModel->count();
        $result = $oWarehouseModel
            ->with(['get_creator_name', 'get_update_name', 'get_country_name', 'get_city_name'])
            ->append(['status_text','is_customs_clearance_text'])
            ->order('id', 'desc')
            ->page($page, $limit)
            ->select();

        // 收集所有需要查询的 transaction_currency_id
        $allCurrencyIds = [];
        foreach ($result as $vo) {
            if ($vo['transaction_currency_id']) {
                $currencyIds = explode(',', $vo['transaction_currency_id']);
                $allCurrencyIds = array_merge($allCurrencyIds, $currencyIds);
            }
        }
        
        // 如果有需要查询的币种ID，一次性查询
        $currencyDict = [];
        if (!empty($allCurrencyIds)) {
            $allCurrencyIds = array_unique($allCurrencyIds);
            $currencies = WarehouseModel::table('db_transaction_currency')
                ->field('id,abbr')
                ->whereIn('id', $allCurrencyIds)
                ->select()
                ->toArray();
            
            // 构建id到abbr的映射
            foreach ($currencies as $currency) {
                $currencyDict[$currency['id']] = $currency['abbr'];
            }
        }

        // 处理每条记录的币种显示
        foreach ($result as &$vo) {
            if ($vo['transaction_currency_id']) {
                $currencyIds = explode(',', $vo['transaction_currency_id']);
                $currencyAbbrs = [];
                foreach ($currencyIds as $id) {
                    if (isset($currencyDict[$id])) {
                        $currencyAbbrs[] = $currencyDict[$id];
                    }
                }
                $vo['transaction_currency_id'] = implode(',', $currencyAbbrs);
            }

            $vo['fl_warehouse_name'] = '一级仓库';
            if (!is_null($vo['fl_warehouse_id'])) {
                $vo['fl_warehouse_name'] = isset($parentName[$vo['fl_warehouse_id']]) ? $parentName[$vo['fl_warehouse_id']] : null;
            }
        }

        $arrData['data'] = ['list' => $result->toArray(), 'total' => $total];
        return $arrData;
    }

    /**
     * 删除单条或多条仓库数据
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete($param)
    {
        $where = [['is_del', '=', '0'], ['id', 'in', $param['ids']]];
        $oWarehouseModel = WarehouseModel::where($where);
        $brand = $oWarehouseModel->find();
        if (!$brand) {
            return ['code' => 1, 'message' => '获取仓库信息失败！'];
        }
        $result = $oWarehouseModel->update(['is_del' => time()]);
        if ($result) {
            $this->logger->logOperation($param['ids'], 'Warehouse', '删除', '删除单条或多条仓库数据');
            return ['code' => 0, 'message' => '删除仓库成功！'];
        } else {
            return ['code' => 1, 'message' => '删除仓库失败！'];
        }
    }

    /**
     * 仓库保存更新
     * @param $param
     * @return array|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function save($param)
    {
        $checkWarehouseModel = WarehouseModel::where([['name', '=', $param['name']], ['is_del', '=', 0]]);
        if ($param['id']) {
            $checkWarehouseModel->where('id', '<>', $param['id']);
        }
        if ($checkWarehouseModel->find()) {
            return ['code' => 1, 'message' => '仓库名称重复！'];
        }

        if ($param['id']) {
            $oWarehouseModel = WarehouseModel::find($param['id']);
            $oWarehouseModel->updater = $param['operator_id'];
            $oWarehouseModel->update_time = date('Y-m-d H:i:s', time());
        } else {
            $oWarehouseModel = new WarehouseModel();
            $oWarehouseModel->creator = $param['operator_id'];
            $oWarehouseModel->create_time = date('Y-m-d H:i:s', time());
            $oWarehouseModel->is_del = 0;
        }

        $oWarehouseModel->name = $param['name'];

        $oWarehouseModel->country = $param['country'];
        $oWarehouseModel->city = $param['city'];
        $oWarehouseModel->state = $param['state'];
        $oWarehouseModel->address = $param['address'];
        $oWarehouseModel->remark = $param['remark'];
        $oWarehouseModel->contact_name = $param['contact_name'];
        $oWarehouseModel->contact_phone = $param['contact_phone'];
        $oWarehouseModel->is_customs_clearance = $param['is_customs_clearance'];
        $oWarehouseModel->transaction_currency_id = $param['transaction_currency_id'];
        $oWarehouseModel->pickup_address = $param['pickup_address'];
        $oWarehouseModel->support_selfpickup = $param['support_selfpickup'];
        $oWarehouseModel->status = $param['status'];
        if ( $param['show_name'] ) {
            $oWarehouseModel->show_name = $param['show_name'];
        }
        $oWarehouseModel->fl_warehouse_id = null;
        if ( $param['fl_warehouse_id'] ) {
            $oWarehouseModel->fl_warehouse_id = $param['fl_warehouse_id'];
        }

        if ($oWarehouseModel->save()) {
            $this->logger->logOperation($oWarehouseModel->id, 'Warehouse', '保存', '保存仓库');
            return ['code' => 0, 'message' => '保存仓库成功！'];
        }
    }

    /**
     * 获取单个仓库信息
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getInfo($param)
    {

        $warehouse = WarehouseModel::where('fl_warehouse_id','EXP','IS NULL')->field('id,name')->select();
        $parentName = [];
        foreach ($warehouse as $key => $value) {
            $parentName[$value['id']] = $value['name'];
        }


        $where = [['is_del', '=', '0'], ['id', '=', $param['id']]];
        $res = WarehouseModel::where($where)
            ->with([
                'get_creator_name',
                'get_update_name',
                'get_country_name',
                'get_city_name'
            ])->append(['is_customs_clearance_text','status_text'])
            ->find();


        if ($res['transaction_currency_id']) {
            $transactionCurrencyIdArr = explode(',', $res['transaction_currency_id']);
            $res['transaction_currency_id'] = array_map(function ($item) {
                return intval($item);
            }, $transactionCurrencyIdArr);
            $transactionCurrency = TransactionCurrencyModel::whereIn('id', $transactionCurrencyIdArr)->column('name');
            $res['transaction_currency_id_text'] = implode(',', $transactionCurrency);
        }

        $res['fl_warehouse_name'] = '一级仓库';
        if ( !is_null($res['fl_warehouse_id']) ) {
            $res['fl_warehouse_name'] = isset($parentName[$res['fl_warehouse_id']]) ? $parentName[$res['fl_warehouse_id']] : null;
        }

        if (!$res) {
            return ['code' => 1, 'message' => '获取仓库信息失败！'];
        }
        return ['code' => 0, 'message' => 'success', 'data' => $res];
    }

    /**
     * 获取下拉框选项
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getSelect()
    {
        $where = [['is_del','=',0]];
        $arrData = ['code' => 0, 'message' => 'success'];

        $oCategoryModel = WarehouseModel::where($where);
        $total = $oCategoryModel->count();
        $result = $oCategoryModel->field('id AS value,name as label')->select();
        $arrData['data'] = ['list' => $result->toArray(), 'total' => $total];
        return $arrData;
    }

    /**
     * 获取二级仓库
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2025-02-20 11 25 27
     * author: jiang
     */
    public function secondWarehouse($disabled = true, $param = [])
    {
        $where[] = ['is_del','=',0];
        $arrData = ['code' => 0, 'message' => 'success'];
        $oCategoryModel = WarehouseModel::where($where);
        if ($param['status']) {
            $oCategoryModel->where('status', $param['status']);
        }
        $result = $oCategoryModel->field('id,name,fl_warehouse_id as parent_id')->select();
        $parentTree = $this->parentTree($result->toArray());
        foreach ($parentTree as $key => &$value) {
            if ( $disabled ) {
                $value['disabled'] = true;
            }
        }

        $arrData['data'] = ['list' => $parentTree];

        return $arrData;
    }

    public function firstWarehouse($param)
    {
        $where = [['is_del','=',0],['fl_warehouse_id','=',null]];
        if ($param['status']) {
            $where[] = ['status','=', $param['status']];
        }
        $arrData = ['code' => 0, 'message' => 'success'];

        $oCategoryModel = WarehouseModel::where($where);
        $total = $oCategoryModel->count();
        $result = $oCategoryModel->field('id AS value,name as label')->select();
        $arrData['data'] = ['list' => $result->toArray(), 'total' => $total];
        return $arrData;
    }

    public function getFieldEnum($field)
    {
        $model = new WarehouseModel();
        $res = $model->getFieldEnum($field);
        return [
            'code' => 0,
            'data' => $res
        ];
    }

    /**
     * 一次性获取修改 添加 下拉框筛选信息
     * @param $field
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getSelectEnum()
    {
        $arrData = ['code' => 0, 'message' => 'success'];
        $data = [];
        $oRegionCountry = new RegionCountry();
        $country = $oRegionCountry->getSelectOption([], "id,CONCAT(cname,' (',full_name,') ') as name");
        $data['country'] = $country;
        $warehouse = WarehouseModel::where(['is_del'=>0])->field('id,name,fl_warehouse_id as parent_id')->select();
        $data['parent'] = $this->parentTree($warehouse->toArray());
        $arrData['data'] = $data;
        return $arrData;
    }

    /**
     * 获取城市远程搜索
     * @param $param
     * @return array
     */
    public function getSearchCity($param)
    {
        $arrData = ['code' => 0, 'message' => 'success'];
        $where = [];
        if ($param['name']) {
            $where['name'] = ['like', '%' . $param['name'] . '%'];
        }

        $oRegionCity = new RegionCity();
        $city = $oRegionCity->getSelectOption($where, "id,name");
        $arrData['data'] = $city;
        return $arrData;
    }

    /**
     * 获取币种下拉框
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-12-04 17 04 34
     * author: jiang
     */
    public function getCurrencySelect($param)
    {
        $arrData = ['code' => 0, 'message' => 'success'];

        $warehouseWhere = [];
        if($param['wid'] && $param['wid'] != ''){
            $warehouseWhere[] = ['id', 'in', explode(',', $param['wid'])];
        }
        // 查询仓库对应币种
        $currency_id = WarehouseModel::where($warehouseWhere)->column('transaction_currency_id');
        if (!$currency_id) {
            return ['code' => 1, 'message' => '获取仓库信息失败！'];
        }
        $currency_arr = [];
        foreach ($currency_id as $item){
            $item_arr = explode(',', $item);
            $currency_arr = array_merge($currency_arr,$item_arr);
        }
        $currency_arr = array_unique($currency_arr);
        $where[] = ['id', 'in', $currency_arr];
        $oTransactionCurrency = TransactionCurrencyModel::where($where);
        $total = $oTransactionCurrency->count();
        $result = $oTransactionCurrency->field('id AS value,name as label')->select();
        $arrData['data'] = ['list' => $result->toArray(), 'total' => $total];
        return $arrData;
    }

    /**
     * 库存盘点
     * @param $productid
     * @param $warehouse_id
     * @param $available_qty_change
     * @param $total_qty_change
     * @param $pending_qty_change
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2025-03-07 16 55 36
     * author: jiang
     */
    public static function productSoldStat($productid, $warehouse_id, $available_qty_change, $total_qty_change, $pending_qty_change)
    {
        $exist = ProductSoldStatModel::where(['productid'=>$productid,'warehouse_id'=>$warehouse_id])->find();
        $oProductSoldStatModel = $exist ?? new ProductSoldStatModel();

        // 如果是新记录，初始化数量字段
        if (!$exist) {
            $oProductSoldStatModel->productid = $productid;
            $oProductSoldStatModel->warehouse_id = $warehouse_id;
            $oProductSoldStatModel->available_qty = $available_qty_change;
            $oProductSoldStatModel->total_qty = $total_qty_change;
            $oProductSoldStatModel->pending_qty = $pending_qty_change;
            $oProductSoldStatModel->create_time = date('Y-m-d H:i:s');
            $oProductSoldStatModel->save();
        }else{
            // 根据传入的变动值更新数量
            if($available_qty_change >= 0){
                $oProductSoldStatModel->inc('available_qty', abs($available_qty_change));
            }else{
                $oProductSoldStatModel->dec('available_qty', abs($available_qty_change));
            }
            if($total_qty_change >= 0){
                $oProductSoldStatModel->inc('total_qty', abs($total_qty_change));
            }else{
                $oProductSoldStatModel->dec('total_qty', abs($total_qty_change));
            }
            if($pending_qty_change >= 0){
                $oProductSoldStatModel->inc('pending_qty', abs($pending_qty_change));
            }else{
                $oProductSoldStatModel->dec('pending_qty', abs($pending_qty_change));
            }
            $oProductSoldStatModel->update_time = date('Y-m-d H:i:s');
        }

        // 保存更新后的记录
        $oProductSoldStatModel->save();
    }

    /**
     *  菜单递归处理
     */
    function parentTree(array $data, $parent_id = 0) {
        $branch = [];
        foreach ($data as $value) {
            $element = [];
            $element['value'] = $value['id'];
            $element['label'] = $value['name'];
            if ($value['parent_id'] == $parent_id) {
                $children = $this->parentTree($data, $value['id']);
                if ($children) {
                    $element['children'] = $children;
                }
                $branch[] = $element;
            }
        }
        return $branch;
    }

}
